/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package n64Controller;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author marcos
 */
public class N64CFrame extends javax.swing.JFrame {

    private Thread controllerThread;
    private N64ControllerReader reader;

    /**
     * Creates new form N64CFrame
     */
    public N64CFrame() {
        initComponents();
        reader = new N64ControllerReader.Instructables(n64ControllerPanelP1.getController());        
        setSerialPortsNames();
        jTabbedPanePlayers.setEnabledAt(1, false);
        jTabbedPanePlayers.setEnabledAt(2, false);
        jTabbedPanePlayers.setEnabledAt(3, false);
    }

    private void setSerialPortsNames() {
        Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
        while (portIdentifiers.hasMoreElements()) {
            Object nextElement = portIdentifiers.nextElement();
            if (nextElement instanceof SerialPort) {
                jComboBoxComPort.addItem(((SerialPort) nextElement).getName());
            }
        }
    }

    private void start() {
        if (controllerThread != null && controllerThread.isAlive()) {
            return;
        }
        try {
            reader.open((String) jComboBoxComPort.getSelectedItem());
            controllerThread = new Thread(reader, "controllerThread");
            controllerThread.setDaemon(true);
            controllerThread.start();
            jTextAreaPlayground.requestFocus();
            status("So it begins: have fun!");
        } catch (NoSuchPortException | IOException ex) {
            status("Houston, we have a problem: " + ex);
            Logger.getLogger(N64CFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (PortInUseException ex) {
            status("Too bad: port in use.");
        }
    }

    private void stop() {
        if (controllerThread != null && controllerThread.isAlive()) {
            reader.stop();
            status("Stoped: come back!");
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel1 = new javax.swing.JPanel();
        jLabelStatusBar = new javax.swing.JLabel();
        jTextAreaPlayground = new javax.swing.JTextArea();
        jTabbedPanePlayers = new javax.swing.JTabbedPane();
        n64ControllerPanelP1 = new n64Controller.N64ControllerPanel();
        n64ControllerPanelP2 = new n64Controller.N64ControllerPanel();
        n64ControllerPanelP3 = new n64Controller.N64ControllerPanel();
        n64ControllerPanelP4 = new n64Controller.N64ControllerPanel();
        jLabel1 = new javax.swing.JLabel();
        jComboBoxComPort = new javax.swing.JComboBox();
        jButtonStart = new javax.swing.JButton();
        jButtonStop = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Arduino64 - Nintendo 64 Controller");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentShown(java.awt.event.ComponentEvent evt) {
                formComponentShown(evt);
            }
        });

        jLabelStatusBar.setText("Status bar...");

        jTextAreaPlayground.setColumns(20);
        jTextAreaPlayground.setLineWrap(true);
        jTextAreaPlayground.setRows(1);
        jTextAreaPlayground.setText("  Playground! =]  ");

        jTabbedPanePlayers.addTab("Player 1", n64ControllerPanelP1);
        jTabbedPanePlayers.addTab("Player 2", n64ControllerPanelP2);
        jTabbedPanePlayers.addTab("Player 3", n64ControllerPanelP3);
        jTabbedPanePlayers.addTab("Player 4", n64ControllerPanelP4);

        jLabel1.setText("Select serial port:");

        jComboBoxComPort.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "COM3" }));

        jButtonStart.setText("Start!");
        jButtonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartActionPerformed(evt);
            }
        });

        jButtonStop.setText("Stop");
        jButtonStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStopActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jTextAreaPlayground)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel1)
                            .addComponent(jComboBoxComPort, 0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(jButtonStart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jButtonStop, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jLabelStatusBar, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPanePlayers))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTabbedPanePlayers, javax.swing.GroupLayout.PREFERRED_SIZE, 409, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jComboBoxComPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonStart)
                    .addComponent(jButtonStop))
                .addGap(18, 18, 18)
                .addComponent(jTextAreaPlayground, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabelStatusBar)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jScrollPane1.setViewportView(jPanel1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
        pack();
        jButtonStart.requestFocus();
        status("Set parameters and click on Start! =]");
    }//GEN-LAST:event_formComponentShown

    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartActionPerformed
        start();
    }//GEN-LAST:event_jButtonStartActionPerformed

    private void jButtonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStopActionPerformed
        stop();
    }//GEN-LAST:event_jButtonStopActionPerformed

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        stop();
    }//GEN-LAST:event_formWindowClosed

    protected void status(String str) {
        jLabelStatusBar.setText(str);
        System.out.println(str);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Windows look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if (info.getName().equals("Windows")) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(N64CFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>


        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new N64CFrame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonStart;
    private javax.swing.JButton jButtonStop;
    private javax.swing.JComboBox jComboBoxComPort;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabelStatusBar;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTabbedPane jTabbedPanePlayers;
    private javax.swing.JTextArea jTextAreaPlayground;
    private n64Controller.N64ControllerPanel n64ControllerPanelP1;
    private n64Controller.N64ControllerPanel n64ControllerPanelP2;
    private n64Controller.N64ControllerPanel n64ControllerPanelP3;
    private n64Controller.N64ControllerPanel n64ControllerPanelP4;
    // End of variables declaration//GEN-END:variables
}
